<script lang="ts" setup>
import type { DictType } from './data';

import { nextTick, onBeforeMount, ref, watch } from 'vue';

import { VIcon } from '@croco/framework/icons';
import { Page } from '@croco/framework/libraries';

import { service } from '#/api/request';

import Edit from './edit.vue';

defineOptions({ name: 'SystemDict' });

const dictTypeRef = ref();
const mainRef = ref();
const editRef = ref<InstanceType<typeof Edit>>();

const dictTreeLoading = ref(false);
const dicTypeList = ref<Array<DictType>>([]);
const currentDict = ref<DictType>({});

// 加载树数据
const onRefreshDictTree = (id?: string) => {
    dictTreeLoading.value = true;
    service
        .get('/system/dict/type')
        .then(({ data }) => {
            dicTypeList.value = data;
            // 获取第一个节点,设置选中 & 加载明细列表
            nextTick(() => {
                dictTypeRef.value.setCurrentKey(id || dicTypeList.value[0]?.id);
            });
        })
        .finally(() => (dictTreeLoading.value = false));
};

// 树过滤
const dicFilterText = ref('');
const dicFilterNode = (value: any, data: any) => {
    if (!value) return true;
    return data.name.includes(value) || data.type.includes(value);
};
watch(dicFilterText, (val) => dictTypeRef.value?.filter(val));

const onDictTypeDelete = (data?: any) => {
    service.confirm({
        message: `确认删除字典类型：${data.name}及其所有键值?`,
        url: '/system/dict/type',
        data: { type: data.type },
        success: () => {
            dictTypeRef.value.remove(data.id);
            // 删除当前菜单时则需要将编辑表单重置，并重新选中其他节点
            if (data.id === currentDict.value.id) {
                currentDict.value = {};
                dictTypeRef.value.setCurrentKey(dicTypeList.value[0]?.id);
            }
        },
    });
};

const onCurrentChange = (data: DictType) => {
    if (data) {
        currentDict.value = data;
        mainRef.value.$el.scrollTop = 0;
    } else {
        currentDict.value = {};
    }
};

// 添加
const onCreate = async () => {
    onSave({
        name: '未知',
        type: Date.now().toString(),
    });
};

// 新增&修改 字典类型信息
const onSave = (form: DictType) => {
    service[form.id ? 'put' : 'post']('/system/dict/type', form).then(({ data }) => {
        if (form.id) {
            const node = dictTypeRef.value.getNode(form.id);
            Object.assign(node.data, data);
        } else {
            // 追加根节点/子节点，并选中当前新节点
            if (dicTypeList.value.length > 0) {
                dictTypeRef.value.insertBefore(data, dicTypeList.value[0]?.id);
            } else {
                dictTypeRef.value.append(data);
            }
            dictTypeRef.value.setCurrentKey(data.id);
        }
    });
};

onBeforeMount(() => {
    onRefreshDictTree();
});
</script>

<template>
    <Page auto-content-height>
        <el-container>
            <el-aside v-loading="dictTreeLoading" width="400px">
                <el-container>
                    <el-header>
                        <el-input v-model="dicFilterText" clearable placeholder="输入关键字进行过滤" />
                        <el-button @click="onRefreshDictTree()" style="margin-left: 6px">
                            <template #icon>
                                <VIcon icon="icon:refresh" />
                            </template>
                        </el-button>
                    </el-header>
                    <el-main style="padding: 0">
                        <el-tree
                            ref="dictTypeRef"
                            :data="dicTypeList"
                            :expand-on-click-node="true"
                            :filter-node-method="dicFilterNode"
                            :highlight-current="true"
                            node-key="id"
                            @current-change="onCurrentChange"
                        >
                            <template #default="{ data }">
                                <span class="custom-tree-node">
                                    <span class="label">{{ data.name }}</span>
                                    <span class="code">{{ data.type }}</span>
                                    <span class="do">
                                        <el-button v-auth="'system:dict:remove'" link type="danger" @click.stop="onDictTypeDelete(data)" />
                                    </span>
                                </span>
                            </template>
                        </el-tree>
                    </el-main>
                    <el-footer style="height: 42px; border: 1px dashed var(--el-border-color)">
                        <el-button v-auth="'system:dict:add'" style="width: 100%" link @click="onCreate()">
                            <template #icon>
                                <VIcon icon="icon:plus" />
                            </template>
                        </el-button>
                    </el-footer>
                </el-container>
            </el-aside>
            <el-container>
                <el-main ref="mainRef" class="kt-edit-main" style="padding: 20px">
                    <Edit ref="editRef" :save="onSave" :dict="currentDict" />
                </el-main>
            </el-container>
        </el-container>
    </Page>
</template>

<style lang="scss" scoped>
.el-container {
    height: 100%;
    .el-aside {
        background-color: var(--el-fill-color-blank);
        border-right: 1px dashed var(--el-border-color);
        .el-header {
            height: 50px;
            display: flex;
            justify-content: center;
            align-items: center;
            border-bottom: 1px dashed var(--el-border-color);
        }
        .el-footer {
            display: flex;
            height: 42px;
            border-top: 1px dashed var(--el-border-color);
        }
    }

    .kt-edit-main {
        background-color: var(--el-fill-color-blank);
    }
}

.el-tree {
    --el-tree-node-content-height: 30px;
}

.custom-tree-node {
    display: flex;
    flex: 1;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    padding-right: 20px;
    height: 100%;
}

.custom-tree-node .code {
    font-size: 12px;
    color: #999;
}

.custom-tree-node .status {
    font-size: 12px;
    color: #999;
}

.custom-tree-node .do {
    display: none;
}

.custom-tree-node .do > .el-button + .el-button {
    margin-left: 12px;
}

.custom-tree-node .do > .el-button.is-circle {
    width: auto;
}

.custom-tree-node .do > .el-button.is-link {
    padding: 0;
}

.custom-tree-node:hover .code {
    display: none;
}

.custom-tree-node:hover .status {
    display: none;
}

.custom-tree-node:hover .do {
    display: inline-block;
}
</style>
